package grouuu;

import grouuu.data.Context;
import grouuu.input.Key;
import grouuu.input.Mouse;
import grouuu.tile.Tiles;
import openfl.display.Sprite;
import openfl.display.StageScaleMode;
import openfl.events.Event;
import openfl.geom.Point;
import openfl.Lib;

/**
 * ...
 * @author Grouuu
 */
class Game
{
	private var scene:Sprite;
	private var context:Context;
	private var originTileX:Int;
	private var originTileY:Int;
	
	private var currentTime:Int;
	private var previousTime:Int;
	
	private var tiles:Tiles;
	private var key:Key;
	private var mouse:Mouse;
	private var world:World;

	public function new(scene:Sprite) 
	{
		this.scene = scene;
		
		init();
	}
	
	// INIT ///////////////////////////////////////////////////////////////////////////////////////
	
	private function init():Void
	{
		scene.stage.scaleMode = StageScaleMode.NO_SCALE;
		
		initContext();
		initTiles();
		initKey();
		initMouse();
		initWorld();
		
		updateDisplayContext();
		
		scene.stage.addEventListener(Event.RESIZE, onResize);
		
		start();
	}
	
	private function initContext():Void
	{
		context = new Context();
		
		context.scene = scene;
		context.tileW = 32;
		context.tileH = 32;
		
		context.controllerType = Context.CONTROLLER_MOUSE;
	}
	
	private function initTiles():Void
	{
		context.tiles = new Tiles(context);
	}
	
	private function initKey():Void
	{
		context.key = new Key(scene.stage);
	}
	
	private function initMouse():Void
	{
		context.mouse = new Mouse(scene.stage);
	}
	
	private function initWorld():Void
	{
		world = new World(context);
		
		world.init();
	}
	
	// START //////////////////////////////////////////////////////////////////////////////////////
	
	private function start():Void
	{
		originTileX = 0;
		originTileY = 0;
		
		previousTime = Lib.getTimer();
		
		scene.stage.addEventListener(Event.ENTER_FRAME, onUpdate);
		
		switch(context.controllerType)
		{
			case Context.CONTROLLER_KEY:
				context.key.start();
			case Context.CONTROLLER_MOUSE:
				context.mouse.start(onClick);
		}
	}
	
	// UPDATE /////////////////////////////////////////////////////////////////////////////////////
	
	private function update(deltaTime:Int):Void
	{
		world.update(deltaTime);
	}
	
	private function updateDisplayContext():Void
	{
		context.stageW = Std.int(scene.stage.stageWidth);
		context.stageH = Std.int(scene.stage.stageHeight);
		context.nbCol = Math.ceil(context.stageW / context.tileW);
		context.nbRow = Math.ceil(context.stageH / context.tileH);
	}
	
	// EVENT //////////////////////////////////////////////////////////////////////////////////////
	
	private function onUpdate(e:Event):Void
	{
		currentTime = Lib.getTimer();
		
		var deltaTime:Int = currentTime - previousTime;
		
		previousTime = currentTime;
		
		update(deltaTime);
	}
	
	private function onResize(e:Event):Void
	{
		updateDisplayContext();
	}
	
	private function onClick(position:Point):Void
	{
		world.targetPositionX = position.x - (context.stageW / 2);
		world.targetPositionY = position.y - (context.stageH / 2);
	}
}